# -*- coding:utf-8 -*-

# @Time    : 2023/5/13 02:24
# @Author  : zengwenjia
# @Email   : zengwenjia@lingxi.ai
# @File    : user_info_extract.py
# @Software: LLM_internal

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
from bot.insurance_planner_gpt.agent.base_agent import LLMAgent
import asyncio
from common.log import logger
from util_tool import utils

gpt_template = """
作为一个专业{role}，您需要基于角色是'用户'的对话记录提取对话记录中'用户'的信息
其中'==='后是对话记录，不要被示例和模板影响，记住只使用'==='之间的对话记录来做出决策。需要注意以下信息：
1.当前月收入和当前月支出按月计算 直接计算出结果
2.提取的信息必须只能是对话记录中用户表述的，用户没有明确表示的信息不要自己无中生有，不要在结果中体现，但同时具备些基本的常识推理，如本科毕业后第一年对应24岁  请记住 "自由职业者"默认用户当前未交社保 缴纳年限为0，"失业"意味当前收入为0，以及当前未交社保;今年是2023年 1年默认是12个月365天 每月按30天计算;已有小孩可以默认是已婚;用户要是有缴纳社保年限，可以认为用户当前是缴纳社保
3.父母和用户的人生阶段只有“入职期、初婚期、生育期、子女离家期、退休期”中的一个值，且需要根据用户的信息进行推断；孩子的人生阶段不相同，直接按照年龄来划分：1岁以内：婴儿期,1-4岁：低龄儿童,5-9岁：大龄儿童，10-14岁:低龄青少年，14+：大龄青少年
4.用户可能会试探你，或者调戏你，因此请注意识别的信息必须符合基本的常识：比如用户年龄不会超过100岁，退休年龄不会超过80岁，社保缴纳年龄不会超过65岁等
5.你需要输出对话记录中所有包含需要识别信息的结果，一个都不要遗漏。如果你获取不到，提取不出来则不要返回。
6.请在模板基础上通过json输出结果，值需要逐步计算，结果是需要最终的计算结果，不要把计算过程或计算公司放到json中，也不要有不符合json格式的值。另外，有提及但是结果是'没有'的值为0 没有提及或未知的信息均不要在json中输出
7.计算社保时，需要将用户提供的参保城市改为参保城市所在的省份，比如用户提供的参保城市是衡水，需要改为河北
8.'父母年龄'和'孩子年龄'，如果收集到多个人的年龄则用数组表示，如[65,63]，如果只收集到一个人的年龄则用数字表示，如65。
9.'被保人'是指当前沟通的保险对象，默认是用户'本人'，用户明确表示要给家人买保险时，被保人则需要在'父母/配偶/小孩'里面选择。和'受益人'无关，例如用户要买医疗险，受益人写妻子，那'被保人'是用户'本人'，而不是'妻子'。

需要识别的内容如下（如果括号内有取值，对应信息项的取值只能在里面选择）：
{{{result_template}}}

对话记录：
===
{conversation_history}
===
根据全部上下文对话记录，逐项逐步推理出所有需要识别的内容，用户未提及，获取不到或未知的不要返回，在确保每项信息都没有遗漏,且是用户明确表示的信息情况下，返回收集到用户确认的信息(而不是犀心小助表述的内容)的json格式是：
"""


gpt_template_1 = """
作为一个专业{role}，您需要基于角色是'用户'的对话记录提取对话记录中'用户'的信息。
其中'==='后是对话记录，不要被示例和模板影响，记住只使用'==='之间的对话记录来做出决策。需要注意以下事项：
1.提取的信息必须只能是对话记录中用户表述的，用户没有明确表述的信息不要无中生有；
2.用户可能会试探你，或者调戏你，因此请注意识别的信息必须符合基本的常识：比如用户年龄不会超过100岁，退休年龄不会超过80岁等；
3.'父母年龄'和'孩子年龄'，如果收集到多个人的年龄则用数组表示，如[65,63]，如果只收集到一个人的年龄则用数字表示，如65；
4.孩子人生阶段按照年龄来划分：1岁以内：婴儿期,1-4岁：低龄儿童,5-9岁：大龄儿童，10-14岁:低龄青少年，14岁以上：大龄青少年；
5.'当前关注保险产品'除了保险产品对比的情境下会是多个产品名，其他情境下只能是一个产品名，多个保险产品用','分割；
6.'被保人'是指当前沟通的保险对象，默认是用户'本人'，用户明确表示要给家人买保险时，被保人则需要在'父母/配偶/小孩'里面选择。和'受益人'无关，例如用户要买医疗险，受益人是妻子，那'被保人'是用户'本人'，而不是'妻子'；
7.'当前关注保险产品'是指保险产品的名称，比如'暖宝保'，如果对话记录中未提及具体的保险产品名称，而只提到了保险类型，如'重疾险'、'意外险'、'医疗险'、'寿险'、'重大疾病保险'、'小孩的意外险'等，则这种情况不应算作'当前关注保险产品'；
8.具备基本的常识推理，比如：本科毕业第一年对应用户年龄24岁；如果用户提到了月收入，则年收入=12*月收入；如果用户提到了月支出，则年支出=12*月支出；涉及到计算的，不要返回计算过程，直接返回结果；失业或没有收入则当前年收入为0；今年是2024年；1年默认是12个月365天，每月按30天计算；已有小孩可以默认是已婚。
9.请特别注意，输出结果一定要是json格式，以下信息是所有要识别的，没有提及或未知的信息则不用在json中输出（如果括号内有取值，对应信息项的取值只能在括号里面选择）:
{{{result_template}}}

对话记录：
===
{conversation_history}
===

根据全部上下文对话记录，逐项逐步推理出所有需要识别的内容，用户未提及，获取不到或未知的不要返回，在确保每项信息都没有遗漏，且是用户明确表示的信息情况下，返回收集到用户确认的信息(不是犀心小助表述的内容)的json格式是：
"""

class UserInfoExtract(LLMAgent):

    def __init__(self, role, conversation_history, user_info_rule):
        self.role = role
        if not conversation_history:
            conversation_history = []
        self.conversation_history = conversation_history

        self.prompt = gpt_template_1.format(role=self.role,
                                          conversation_history=self.conversation_history,
                                          result_template=user_info_rule)
        print(self.prompt)
        super().__init__(self.prompt)


if __name__ == '__main__':
    from bot.insurance_planner_gpt.user_info import UserInfo

    user_info_rule = UserInfo().user_info_rule
    conversation_history1 = """
     犀心小助:您好！🌞我是犀心小助，您的专属保险规划师，活泼热情，细心周到是我的特点哦！如有关于保险规划或保险产品等相关的问题，我都能帮您解答哦！😊现在有什么我可以帮您的吗？
用户:我对个人保险规划有些疑问
犀心小助:对于个人保险规划，那是一项重要的任务，很高兴您能重视这个问题！😊首先，我们需要明确一下，您规划保险的主要目的是什么呢？比如是为了针对意外风险提前做保障，还是计划通过保险进行理财增值呢？             
用户:我说错了，我还是想做家庭的保险规划
犀心小助:好的，没问题！家庭保险规划确实很重要，能帮助我们在遇到突发事件时，能有足够的经济保障。😊为了能提供更贴切的建议，我需要了解一下几个关键信息：
1. 家庭的保险规划核心对象是谁呢？是您自己，还是包括家人？
2. 您的预期保险预算大概是多少呢？
3. 您希望通过保险规划达到什么样的目标呢？例如保障家庭生活，子女教育，遗产传承等。
这些信息可以帮助我为您做出更加精准的保险规划，期待您的回复呀！😊
用户:我35岁，受益人是我的父母 我每月收入20000元 年支出10000元
犀心小助：我这边有个众民保普惠百万医疗险（单人版）-普通版，保额建议在100万以上。正好符合一般的医疗保险建议，只要您的年保费预算在790元左右，就能享受这样的保障。"""
    conversation_history = """

犀心小助:您好！😊在这阳光明媚的一天，有什么可以助您一臂之力呢？无论是关于保险规划的困惑，还是想要了解更多保险产品信息，我都在这里为您准备好了，随时听候您的吩咐哦！🌟

用户:小助你好

犀心小助:嘿嘿，感谢您的回复！🌼我在这里就是为了帮助您梳理保险需求，确保您的保险规划全面而周到。🛡️
保险规划对于个人和家庭来说，就像一把保护伞，不管天气晴朗还是风雨交加，都能给您一个安心的保障。无论是意外、疾病还是其他突发状况，良好的保险规划都能让您和家人减轻经济上的压力。💪
现在，我们可以一起来聊聊您对保险的看法，或者您未来可能有的一些计划，比如结婚、买房等。这些都将对您的保险需求产生影响。🔍您有没有考虑过这方面的事情呢，或者对不同类型的保险有什么疑问或者想了解的呢？📝

用户:我是李嘉宽

犀心小助:您好，李嘉宽先生！🎉很高兴可以为您的保险规划提供帮助。为了让我更好地了解您的情况，方便后续为您提供更贴合的建议，您能跟我分享一下您当前的生活情况吗？比如您的职业类型、家庭状况以及是否有定期的经济负担等。还有就是，您在未来有没有什么特别的计划或者目标，比如买房、出国旅游等等？🏡✈️了解这些后，我们可以进一步讨论您的保险需求。😊

用户:我想投保一份保险

犀心小助:好的，李嘉宽先生，投保是个负责任的决定，我会尽全力为您提供合适的建议。😃首先，我想了解一下您投保的初衷。是出于对某种风险的防范（比如意外、医疗、重疾），还是有长期的财务规划需求（比如养老、教育金）？同时，您对保险的预算有什么特定的考虑吗？这样我可以更精准地为您推荐合适的保险产品哦！🌷📊

用户:对于风险的防范

犀心小助:好的，既然您考虑的是风险防范，我们可以从保险的基础功能说起。😌保险产品大致可以分为重疾险、医疗险和定期寿险等几大类。
1.重疾险主要是在您不幸确诊合同约定的严重疾病时，能够获得一笔理赔金，用来减轻因疾病而带来的经济负担。
2.医疗险的保障重点在于医疗费用，能够为您支付日常医疗支出，比如住院、手术、药费等，通常按比例报销。
3.如果您还考虑到家庭的经济安全，定期寿险能在您意外身故或全残时为您的家人提供一笔资金，以保障他们的未来生活。
根据您的具体需求，我们可以细化选择。比如，您是更担心重疾带来的经济影响，还是日常的医疗费用，或者考虑到家庭财务安全，您更偏向于选择定期寿险？同时，能告诉我您的预算范围吗？这样我可以更好地帮您筛选适合的产品。🌿📈

用户:担心意外和想到给家庭的保障一笔基金

犀心小助:了解到您既担心意外风险，又想为家庭提供经济保障，我们可以根据您的需求，整合出一个保险规划方案。😊
对于意外风险的防范，意外险能提供相关保障，常规的意外险包括意外身故和伤残赔付。另外，为了给家庭提供一笔经济基金，您可以考虑定期寿险，它在您身故后能给家人留下一笔资金。
我们现在来确定一下，您希望这份保障金大概是多少？这会帮助我们更好地选择保额。😉另外，您对投保预算有什么特定的想法或限制吗？这样我们可以在您的财务能力范围内，选择最符合您需求的产品。👌🌺
用户:我不太清楚保障金是多少50w?
犀心小助:了解了，您想为家庭提供的保障金大致为50万元，那么我来为您解释一下这个金额是否合适。😊
一般来说，保障金的金额应该根据您的年收入、家庭经济状况以及可能的未来负担来估算。比如，一般建议的保障金至少是您年收入的5到10倍，这样可以确保家庭在发生不幸情况时，能有足够的资金来维持生活、教育孩子或支付未来的债务。
如果按照这个标准，50万元对您来说是否足够？您可以考虑您的年收入、家庭支出以及任何债务等因素来判断。🤔同时，您能提供一下您每年的预算范围吗？这样我们可以更好地进行保费的计算和产品选择。💰📋

用户:年收入20w，家庭支出6w有房贷每月还6000

犀心小助:根据您的年收入20万元和家庭年支出6万元，再加上每月6000元的房贷支出，这些信息有助于我们评估合适的保障金。😌50万作为一个起始点是个不错的选择，但我们可以根据您的具体情况进一步详细规划。首先，根据您的年收入，通常建议的保额范围是年收入的5到10倍，这样在发生不幸时，可以为家庭提供足够的经济支持，确保生活水平不受太大影响。基于您的年收入，这个数字大概在100万到200万之间。📊
其次，您的家庭年支出6万元，加上房贷，意味着您每年至少需要72万元来维持目前的生活水平。这部分至少需要被保险所覆盖。另外，考虑到可能发生的意外，我们还需要添加额外的保障。
所以，结合您的年收入、家庭支出以及房贷情况，我初步建议保额在100万到200万之间。接下来，我需要知道您对于保费的预算有何考虑？这样我们就能够在您的财务承受范围内为您推荐合适的产品了。💡👍

用户:保额100万到200万是200万减去72万算出来的嘛‘’

犀心小助:明白您的疑问啦！😄实际上，推荐的保额100万到200万并不是直接从200万中减去家庭年支出72万计算出来的，而是综合考虑您的年收入、家庭年支出和负债等因素后，给出的一个大致的保额建议范围。该范围旨在确保在发生不幸事件时，家庭能得到足够的经济支持以维持现有生活水平。💼
确定保额时，我们通常会考虑以下几个方面：
1.年收入：建议保额为年收入的5到10倍。
2.家庭支出：确保至少覆盖常规的生活费用。
3.负债：比如房贷，需要计入保额以确保债务在不幸事件时能得到偿还。
4.特殊费用：如果您有小孩或老人需要赡养，这些费用也需要考虑进去。
您觉得这样的解释清楚吗？😊接下来，我们来确定您每年的保费预算范围，这样我就可以帮您筛选合适的保险产品了。💡🌸

用户:好的，选产品吧

犀心小助:好的，我们来看一下适合您的保险产品。😊
根据您的情况，您期望的保额是100万到200万之间，而您的年保费预算为2400元。为了给您的家庭提供意外保障和经济安全，我们可以考虑组合两种保险：定期寿险和意外险。
1.定期寿险：这类保险可以在您不幸身故时为您的家人提供一笔资金，保障他们的经济安全。根据保额100万到200万的需求，预估的年保费大概在数千元左右。但鉴于您的年保费预算较为有限，我们可能需要在保额上适当调整。
2.意外险：意外险的保费相对较低，通常只需几百元，它提供意外身故和伤残的保障。考虑到预算，我们可以选择一款基本的意外险产品，以提供基础意外保障。
我可以帮您挑选一款保费在您预算内的定期寿险产品，并组合一款基本的意外险产品。这样的组合可以在保障意外风险的同时，提供一定程度的家庭经济安全保障。🛡️
如果您觉得这样的方案合适，我会继续为您推荐具体的产品。或者，如果您有其他想法或需求，也可以告诉我，我们一起进一步讨论。🌟🌿

用户:我的年保费预算我没有提及吧

犀心小助:对不起，好像有一点误会。从对话中我们看到，您表达了对意外风险的防范和为家庭提供保障金的需求。您提出了一个大致的保障金数额为50万元，并且告知了年收入为20万元、家庭年支出为6万元，房贷每月6000元，但是并没有明确提到您的年保费预算。因此，犀心小助给出的2400元年保费预算可能是基于常规考量或者误解了您的情况。
对于您的保险需求，建议的方案是组合定期寿险和意外险。这样的方案能够同时满足您避免意外风险和为家庭提供经济安全的需求。
-定期寿险能在您意外身故的情况下，给家人提供约定的理赔金。这份保障可以是您提出的50万元，或者根据您的年收入、负债和家庭支出，可能需要增至100万到200万之间。但具体的保额需根据您的预算来定。
-意外险则能提供意外身故和伤残的保障，保费较低，根据不同的保额和条款，价格会有所变动。
请您根据自己的实际预算考虑，如果您有具体的年保费预算，请告知我们，以便我们能够为您推荐确切符合您财务状况的保险产品。如果还有任何疑问或需要调整保额，请随时告知。我们会基于您的情况和预算，为您推荐更合适的保险产品和保额。

用户:好的，定期寿险保额200w再加上意外险你来计算一下保费、

犀心小助:当然可以呢！😊让我来为您计算一下保费。
1.定期寿险保额200万：根据您的年龄、健康状况和所选的保障期限，定期寿险的年保费通常在几千到一万元之间。以健康的中青年为例，如果在30-40岁之间，保费可能在4000-8000元左右，但这只是一个粗略估计，具体保费还需要根据保险公司的定价和产品细节来确定。
2.意外险：基本的意外险年保费相对较低，通常在几百元左右。如果您希望加上一份意外保障，假设保额为50万元，年保费可能在200-500元之间。
综合起来，如果您选择定期寿险保额200万元再加上意外险保额50万元，年保费的总额可能在4200元到8500元之间。请注意，这只是一个初步的估计，具体保费需要根据选择的保险公司和产品来确定。
接下来，您希望选择哪家保险公司的产品，还是希望我为您推荐一些符合这个保费预估的产品供您参考呢？请您告诉我，这样我们可以进一步聊下去。🌼📋

用户:我今年45岁是物流配送人员，家在湖北随州

犀心小助:好的，李嘉宽先生，根据您45岁的年龄和从事物流配送工作这一职业属性，您属于相对高风险的职业群体。😌这可能会影响到保险的费率，具体来说：
-定期寿险：由于年龄和高危职业的因素，对应的年保费可能会高于普通职业人士。根据市场情况，定期寿险的年保费估计可能在1万元左右，这需要根据保险公司的具体评估来确定。
-意外险：同样地，由于职业风险较高，意外险的保费也可能比普通职业的人士稍高。如果保额为50万元，年保费的预估可能在数百元到一千元左右，具体则要看保险公司的产品条款和职业加费情况。
综合起来，如果我们考虑定期寿险保额200万元加上意外险保额50万元，您的年保费可能介于一万几千元到两万元之间，作为一个保守估计。当然，确切的保费需要向保险公司咨询才能得到准确的报价。
请问您是否需要我为您推荐具体的保险产品，还是有其他的保障需求和考虑？🌟🛡️

用户:好的，每年保费1w左右有没有推荐的保险呢

犀心小助:既然您的年保费预算大约在1万元左右，我将在这个范围内为您推荐一些保险产品组合。😊
1.定期寿险：考虑到定期寿险保额200万元，对于您45岁的年龄和高风险职业，建议选择那些针对高风险职业有特别设计的定期寿险产品，保费可能会更划算。预估年保费可能在8000元左右。
2.意外险：为补充意外风险的保障，可以考虑一款基本的意外险，预估保额50万元，年保费可能在500元到1000元之间。
综合起来，如果您选择一款定期寿险保额200万元的产品，再加上50万元保额的意外险，预估年保费可能介于8500元到9000元之间。
具体产品方面，我们可以看一下平安保险的「平安e生保」产品，它是一款性价比较高的定期寿险，适合您的预算和需求。以及，中国平安的「安行宝」意外险，也是一款适合您职业类别的意外险产品。这两款产品组合起来，大致符合您1万元左右的年保费预算。
请注意，以上只是一个初步的推荐和估计，具体保费和保额需要根据保险公司最新的产品条款和费率表来确定。如果您需要更详细的信息，我建议您咨询保险公司，以获取确切的保费报价和完整的产品说明。👌📝
希望这些建议对您有帮助，如果您有其他问题或需要进一步的帮助，请随时告诉我。我们会继续为您服务的！🌟🌼

用户:好的，介绍一下华贵大麦甜蜜家


"""
    user_info_extract = UserInfoExtract(role='保险规划师',
                                        conversation_history=conversation_history.strip().replace('\n\n', '\n'),
                                        # conversation_history='你好',
                                        user_info_rule=user_info_rule)
    user_info_gpt = asyncio.run(user_info_extract.achat_auto_llm(type="gpt"))
    # user_info_self = asyncio.run(user_info_extract.achat_auto_llm(type="zephyr"))
    user_info_cn = utils.json_load_llm_result(user_info_gpt)
    logger.info('user_info_gpt:\n' + str(user_info_gpt) + '\nuser_info_self:\n' + str(user_info_cn))
